package com.pf.export;

import com.google.common.collect.Lists;
import com.pf.utils.ExportExcelUtils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 级联下拉列表
 * <p>
 * Excel·VBA自定义正则表达式函数、使用
 * 参考博客：https://blog.csdn.net/hhhhh_51/article/details/123745352
 *
 * @author PanFei
 * @version 1.0.0
 * @createTime 2023/3/4 20:29
 */
public class CascadeDropDownListDemo_Plus {

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class Criteria {
        private String criteriaName;
        private String firstCategory;
        private String secondCategory;
    }

    public static void main(String[] args) throws Exception {
        createCascadeDropDownList();
    }

    /**
     * 创建省市区三级联动下拉列表
     */
    private static void createCascadeDropDownList() throws Exception {

        List<String> headTitles = Lists.newArrayList("审核准则名称", "一级分类", "二级分类");
        String property = System.getProperty("user.dir");
        String filePath = property + "/basic-demo/src/main/resources/CascadeDropDownListTemplate.xlsm";
        File file = new File(filePath);
        XSSFWorkbook workbook = new XSSFWorkbook(file);
        String sheetName = "审核准则";
        XSSFSheet sheet = workbook.getSheetAt(0);
        workbook.setSheetName(0, sheetName);
        // 创建表头
        int rowIndex = 0;
        XSSFRow headRow = sheet.createRow(rowIndex);
        for (int i = 0; i < headTitles.size(); i++) {
            XSSFCell headCell = headRow.createCell(i);
            headCell.setCellValue(headTitles.get(i));
        }

        // 数据行显示级联下拉
        List<Criteria> dataList = getExcelData();
        for (int i = 0; i < dataList.size(); i++) {
            rowIndex = rowIndex + 1;
            XSSFRow dataRow = sheet.createRow(rowIndex);
            Criteria criteria = dataList.get(i);
            XSSFCell provinceCell = dataRow.createCell(0);
            provinceCell.setCellValue(criteria.getCriteriaName());

            XSSFCell cityCell = dataRow.createCell(1);
            cityCell.setCellValue(criteria.getFirstCategory());

            XSSFCell areaCell = dataRow.createCell(2);
            areaCell.setCellValue(criteria.getSecondCategory());
        }

        // 1.先为【审核准则名称】列设置下拉选项
        List<String> criteriaNameList = getCriteriaNameList();
        ExportExcelUtils.createUnlimitedDropDownList(workbook, sheetName, 0, 0, criteriaNameList);


        // 2.再为【一级分类】【二级分类】列设置下拉选项
        // 2.1.先生成excel名称管理器
        Map<String, List<String>> targetMap = getCriteriaMap();
        ExportExcelUtils.createSheetNameManger(workbook, 1, targetMap, true);
        // 2.2.为【一级分类】【二级分类】设置联动下拉
        ExportExcelUtils.createCascadeDropDownList(workbook, sheetName, 1, "\"_\"&$A2", true);
        ExportExcelUtils.createCascadeDropDownList(workbook, sheetName, 2, "\"_\"&$A2&\"_\"&$B2", true);

        // 3.输出账单excel
        workbook.write(new FileOutputStream("D:/test/criteriaNameCategory.xlsm"));
        System.out.println(">>>> 导出成功...");
    }

    private static List<String> getCriteriaNameList() {
        return Lists.newArrayList("智选准则", "车规准则");
    }

    /**
     * 模拟的三级联动下拉选项信息
     *
     * @return
     */
    private static Map<String, List<String>> getCriteriaMap() {
        /**
         * 智选准则  智选@一级分类  智选二级分类
         * 智选准则  智选@一级分类  智选二级分类2
         * 智选准则  智选一级分类  智选二级分类
         * 智选准则  其他一级  其他二级
         * 车规准则  车规:一级分类  车规二级分类
         * 车规准则  车规:一级分类  车规二级分类2
         * 车规准则  其他一级  其他二级
         */

        Map<String, List<String>> map = new HashMap<>();
        /**
         * 问题1.组装名称管理器数据时，为什么key要以下划线开头？
         * 解答:考虑准则名称列万一选项是（A2或B2），名称管理器也会报错，因为excel会将其当做特殊符号处理。
         *
         * 问题2：因需求中一级分类列有（其他一级）选项是重复的，但所属的准则名称不一样，需要处理，不然创建名称管理器时，会发生重名现象。
         * 解答:所以一级分类对应的名称管理器名称使用：【准则名称_一级分类】格式将其连接，这样就不会重复。
         */

        map.put("_智选准则", Lists.newArrayList("智选@一级分类", "智选一级分类", "其他一级"));
        map.put("_车规准则", Lists.newArrayList("车规:一级分类", "其他一级"));
        map.put("_智选准则_智选@一级分类", Lists.newArrayList("智选二级分类", "智选二级分类2"));
        map.put("_智选准则_智选一级分类", Lists.newArrayList("智选二级分类"));
        map.put("_智选准则_其他一级", Lists.newArrayList("其他二级"));
        map.put("_车规准则_车规:一级分类", Lists.newArrayList("车规二级分类", "车规二级分类2"));
        map.put("_车规准则_其他一级", Lists.newArrayList("其他二级"));
        return map;
    }

    /**
     * excel列表显示的数据行信息
     *
     * @return
     */
    private static List<Criteria> getExcelData() {
        Criteria c1 = new Criteria("智选准则", "智选@一级分类", "智选二级分类");
        Criteria c2 = new Criteria("车规准则", "其他一级", "其他二级");
        return Lists.newArrayList(c1, c2);
    }


}
